package Operations;

import java.lang.StringBuffer;
import java.util.Random;

import util.GAConfig;

public class ValuesGenerator {



	  /**
	   * The random number used any testtime a random choice is made. (Developer note:
	   * do not declare new Random objects; use this one instead).
	   */
	public  static Random random;// = new Random(GAConfig.RANDOM_SEED);

	 public static void reset(long newSeed){
	    random = new Random();
	    random.setSeed(newSeed);
	  }

	public static int getRandomInt( int max) {
//		System.out.println("GAConfig.RANDOM_SEED"+GAConfig.RANDOM_SEED);
		int randomNumber= random.nextInt(max);
		return randomNumber;
		
	}
	public static int getRandomIntBetween(int min, int max) {
	
		long range       = (long)max - (long)min + 1;
		long fraction    = (long)(range * random.nextDouble());
	    int randomNumber = (int)(fraction + min);
		return randomNumber;
	}

	public static float getRandomFloat() {
		return random.nextFloat();
	}

	public static double getRandomDouble() {
		return random.nextDouble();
	}

	public static boolean getBoleean(float prob){
		return random.nextFloat() < prob;
	}
	public static String buildValue(String type) {

		if (type.startsWith("java.lang.Integer")||type.startsWith("int"))
			return buildIntValue();
		else 
			if (type.toLowerCase().contains("float") ||type.toLowerCase().contains("double")) 
				return buildRealValue(type);
			else
				if (type.toLowerCase().contains("boolean"))
					return buildBoolValue(type);
				else
					if(type.toLowerCase().contains("char"))
						return buildCharacterValue();
					else
					return buildStringValue(type);
	}
	public static String modifyValue(String type,String sugesstedValue) {
		Object valueObj;
		if (type.startsWith("java.lang.Integer")||type.startsWith("int"))
			 valueObj=mapValueToObject(java.lang.Integer.class,sugesstedValue);
		else 
			if (type.startsWith("float") ||type.startsWith("java.lang.Float")) 
				 valueObj=mapValueToObject(java.lang.Float.class,sugesstedValue);
			else
				if (type.startsWith("double")|| type.startsWith("java.lang.Double"))
						valueObj=mapValueToObject(java.lang.Double.class,sugesstedValue);
			else
				if (type.startsWith("boolean"))
					 valueObj=mapValueToObject(java.lang.Boolean.class,sugesstedValue);
				else
					 valueObj=mapValueToObject(java.lang.String.class,sugesstedValue);
		if(valueObj!=null)
			return sugesstedValue;
	return null;
	
	}
	
	
	public static String buildBoolValue(String type) {
		int n = getRandomInt(100);
		if (n < 50)
			return "true";
		else
			return "false";
	}
	public static String buildIntValue() {
	//	int n =getRandomIntBetween(0, GAConfig.N);
		int n =getRandomIntBetween(GAConfig.N*-1, GAConfig.N);
		return Integer.toString(n);
	}
	public static String buildStringValue(String type) {
		String str;
		StringGenerator stringGenerator = new StringGenerator();
			str = stringGenerator.newString(GAConfig.SET_TO_NULL);
		if(str==null)
			return null;
		return str;
		//return "\"" + str + "\"";
	}

	public static String buildCharacterValue() {
		return ""+characterGenerator.getCharacter();
		
	}
	 public static String buildRealValue(String type) {
		    int lowBound = 0;
		    int upBound = 100;
		    double n = lowBound + 
		    getRandomInt(1000 * (upBound - lowBound) + 1) / 1000.0;
		//   int r =getRandomIntBetween(0, GAConfig.N);
		    int r =getRandomIntBetween(GAConfig.N*-1, GAConfig.N);
		    if(r<0)
		    		n=-1* n;
		    return Double.toString(n);
		  }
	 public static String stringValueMuteated(String actuallValue,String pSuggestValue){
		 if(actuallValue!=null&&actuallValue.length()>40)
			 System.out.println("ValuesGenerator.stringValueMuteated : actuallValue= "+ actuallValue.toString());
		 if(actuallValue==null){
	//		 System.out.println("ValuesGenerator.string ValueMuteated: actuallValue=null");
			 actuallValue="";
		 }
			/** probability to add a char before the selected char */
			 float probAddChar = 0.5f;

			/** probability to remove the selected char */
			 float probRemoveChar = 0.0f;

			/**  probability to modify the selected char  */
			 float probModifyChar = 0.5f;
			 String newValue=null;
		 if(pSuggestValue==null)
			 return newValue;
		 else
			 newValue=pSuggestValue.toString();

		 final boolean isModifiable = actuallValue.length() > 0  ;//&& (methodsRecommend.containsKey("init"));

		final boolean isRemovable = actuallValue.length()>0;
		 
		 int choice;
		 if(isModifiable && isRemovable) {
			float c = ValuesGenerator.getRandomFloat() * (probAddChar + probRemoveChar + probModifyChar);
			if(c < probAddChar) choice = 0;
			else if(c < probAddChar + probModifyChar) choice = 1;
			else choice = 2;
		} else if(isModifiable) {
			float c = ValuesGenerator.getRandomFloat() * (probAddChar + probModifyChar);
			if(c < probAddChar) choice = 0;
			else choice = 1;
		} else if(isRemovable) {
			float c = ValuesGenerator.getRandomFloat()* (probAddChar + probRemoveChar);
			if(c < probAddChar) choice = 0;
			else choice = 2;
		} else choice = 0;
	
		 int postition=0;
		 if(actuallValue.length()!=0)
			 	postition=ValuesGenerator.getRandomInt(actuallValue.length());
		 
		if(choice==0)// add a suggested value to the string
			newValue = new StringBuffer(actuallValue).insert(postition, pSuggestValue).toString();
		if(choice==1)//modify a char
			newValue = actuallValue.substring(0,postition)+ pSuggestValue  +actuallValue.substring(postition+1);
		
		return newValue;
	 }
	 public  static Object mapValueToObject(Class<?> valType,String val) {
			Object obj = null;
			if(val==null||val.equals("null"))
				return obj;
			try{
				if (valType ==  java.lang.String.class)
					obj = new java.lang.String(val.trim());
				else if (valType ==  java.lang.Integer.class||valType == int.class)
					obj = new Integer(Integer.parseInt(val.trim()));
				else if (valType ==  java.lang.Double.class|| valType ==double.class)
					obj = new Double(Double.parseDouble(val.trim()));
				else if (valType ==  java.lang.Boolean.class|| valType ==boolean.class)
					obj = new Boolean(Boolean.parseBoolean(val.trim()));
				else if (valType ==  java.lang.Character.class|| valType ==char.class)
					obj = new Character((char) val.charAt(0));
//				else System.out.println("Error: ** ReflectionExecutor.mapValueToObject **"+ valType);
			}catch(Throwable e){
				return null;
			}


			return obj;
		}

	 public static void main(String args[]) {
		 ValuesGenerator.reset(10);
		    while(true)
		      System.out.println(0+(ValuesGenerator.getBoleean(.5f) ? -1 : 1));
		    
		  }
}
